/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.log.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bstek.ureport.utils.DataUtils;
import lombok.AllArgsConstructor;
import org.springblade.common.enums.IntegralGenerateType;
import org.springblade.common.enums.IntegralType;
import org.springblade.common.exception.TrainingServiceException;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.course.entity.CourseEntity;
import org.springblade.modules.course.vo.CourseVO;
import org.springblade.modules.log.entity.IntegralLogEntity;
import org.springblade.modules.log.entity.IntegralTrainingEntity;
import org.springblade.modules.log.entity.IntegralTrainingLogEntity;
import org.springblade.modules.log.entity.IntegralYearLogEntity;
import org.springblade.modules.log.service.IIntegralYearLogService;
import org.springblade.modules.log.vo.IntegralLogVO;
import org.springblade.modules.log.excel.IntegralLogExcel;
import org.springblade.modules.log.mapper.IntegralLogMapper;
import org.springblade.modules.log.service.IIntegralLogService;
import org.springblade.modules.log.vo.IntegralViewVO;
import org.springblade.modules.log.wrapper.IntegralLogWrapper;
import org.springblade.modules.material.entity.PaperReleaseEntity;
import org.springblade.modules.personal.entity.UserBaseEntity;
import org.springblade.modules.personal.service.IUserBaseService;
import org.springblade.modules.system.entity.User;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 积分项导入日志 服务实现类
 *
 * @author junxin
 * @since 2023-05-18
 */
@Service
@AllArgsConstructor
public class IntegralLogServiceImpl extends BaseServiceImpl<IntegralLogMapper, IntegralLogEntity> implements IIntegralLogService {
	private final IIntegralYearLogService integralYearLogService;
	private final IUserBaseService userBaseService;

	@Override
	public IPage<IntegralLogVO> selectIntegralLogPage(IPage<IntegralLogVO> page, IntegralLogVO integralLog) {
		return page.setRecords(baseMapper.selectIntegralLogPage(page, integralLog));
	}


	@Override
	public List<IntegralLogExcel> exportIntegralLog(Wrapper<IntegralLogEntity> queryWrapper) {
		return baseMapper.exportIntegralLog(queryWrapper);
	}

	@Override
	public IPage<IntegralViewVO> selectIntegralByUserId(IPage<IntegralViewVO> page, IntegralViewVO vo) {
		return page.setRecords(baseMapper.selectIntegralByUserId(page, vo));
	}

	@Override
	public List<IntegralLogEntity> selectByIdcard(String idcard) {
		QueryWrapper<IntegralLogEntity> queryWrapper = new QueryWrapper<>();
		if (StringUtil.isNotBlank(idcard)) queryWrapper.lambda().eq(IntegralLogEntity::getUserNumber, idcard);
		return baseMapper.selectList(queryWrapper);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean addIntegral(IntegralLogVO vo) {

		UserBaseEntity userBaseEntity = new UserBaseEntity();
		if (null != vo.getUserId())
			userBaseEntity = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserId, vo.getUserId()));
		else if (Func.isNotEmpty(vo.getUserNumber()) )
			userBaseEntity = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserNumber, vo.getUserNumber()));
		else if (Func.isNotEmpty(vo.getUserName()) )
			userBaseEntity = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserName, vo.getUserName()));

		if (null == userBaseEntity) return true;
		String year = DateUtil.format(new Date(), "yyyy");//当前年度
		if (null == vo.getYear()) vo.setYear(year);
		vo.setUserName(userBaseEntity.getUserName());
		vo.setUserNumber(userBaseEntity.getUserNumber());
		if (ObjectUtil.isEmpty(vo.getIntegralGenerateType()) && ObjectUtil.isNotEmpty(vo.getIntegralResourcesId()))
			vo.setIntegralGenerateType(IntegralGenerateType.SYSTEM.getCode());
		if (ObjectUtil.isEmpty(vo.getIntegralGenerateType()) && ObjectUtil.isEmpty(vo.getIntegralResourcesId()))
			vo.setIntegralGenerateType(IntegralGenerateType.IMPORT.getCode());

		IntegralLogEntity integralLogEntity = this.getOne(Wrappers.<IntegralLogEntity>query().lambda()
			.eq(IntegralLogEntity::getUserId, vo.getUserId())
			.eq(IntegralLogEntity::getYear, year)
			.eq(IntegralLogEntity::getIntegralType, vo.getIntegralType())
			.eq(IntegralLogEntity::getIntegralResourcesId, vo.getIntegralResourcesId()));
		if (null != integralLogEntity) return true;

		//添加个人总积分
		if (null != vo.getIntegral()) userBaseEntity.setIntegral(vo.getIntegral() + userBaseEntity.getIntegral());
		if (null != vo.getPeriod()) userBaseEntity.setPeriod(vo.getPeriod() + userBaseEntity.getPeriod());
		userBaseService.updateById(userBaseEntity);
		return this.save(vo) && integralYearLogService.addYearIntegral(userBaseEntity.getUserNumber(), userBaseEntity.getUserName(), vo.getYear(), vo.getIntegral(), vo.getPeriod());
	}

	@Override
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public boolean addIntegralImport(IntegralLogVO vo) {
		List<UserBaseEntity> userBaseEntityList = userBaseService.list(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserName, vo.getUserName()));
		if (Func.isEmpty(userBaseEntityList))throw new TrainingServiceException("没找到此人:" + vo.getUserName());
		if (userBaseEntityList.size()>1) throw new TrainingServiceException("系统中找到相同名字的用户数据:" + vo.getUserName());

		UserBaseEntity userBaseEntity=userBaseEntityList.get(0);
		String year = DateUtil.format(new Date(), "yyyy");//当前年度
		if (null == vo.getYear()) vo.setYear(year);
		vo.setUserName(userBaseEntity.getUserName());
		vo.setUserNumber(userBaseEntity.getUserNumber());

		if (ObjectUtil.isEmpty(vo.getIntegralGenerateType()) && ObjectUtil.isNotEmpty(vo.getIntegralResourcesId()))
			vo.setIntegralGenerateType(IntegralGenerateType.SYSTEM.getCode());
		if (ObjectUtil.isEmpty(vo.getIntegralGenerateType()) && ObjectUtil.isEmpty(vo.getIntegralResourcesId()))
			vo.setIntegralGenerateType(IntegralGenerateType.IMPORT.getCode());

		IntegralLogEntity integralLogEntity = this.getOne(Wrappers.<IntegralLogEntity>query().lambda()
			.eq(IntegralLogEntity::getUserName, vo.getUserName())
			.eq(IntegralLogEntity::getYear, year)
			.eq(IntegralLogEntity::getIntegralType, vo.getIntegralType())
			.eq(IntegralLogEntity::getIntegralOrigin, vo.getIntegralOrigin())
			.eq(IntegralLogEntity::getProjectOrigin, vo.getProjectOrigin()));
		if (null != integralLogEntity) return true;//表示已经记录过了

		//添加个人总积分
		if (null != vo.getIntegral()) userBaseEntity.setIntegral(vo.getIntegral() + userBaseEntity.getIntegral());
		if (null != vo.getPeriod()) userBaseEntity.setPeriod(vo.getPeriod() + userBaseEntity.getPeriod());
		userBaseService.updateById(userBaseEntity);
		return this.save(vo) && integralYearLogService.addYearIntegral(userBaseEntity.getUserNumber(), userBaseEntity.getUserName(), vo.getYear(), vo.getIntegral() == null ? 0 : vo.getIntegral(), vo.getPeriod() == null ? 0 : vo.getPeriod());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateIntegral(IntegralLogEntity entity) {
		IntegralLogEntity oldData = this.getById(entity.getId());
		String year = DateUtil.format(oldData.getCreateTime(), "yyyy");
		//1.对比用户是否改变
		if (null == entity.getUserName()) throw new TrainingServiceException("用户名称不能为空");
		if (null == entity.getIntegral() || entity.getIntegral() < 0) throw new TrainingServiceException("积分不能为空且需大于0");

		if (entity.getUserName().equals(oldData.getUserName())) {
			//用户没有改变，则对比积分差异
			if (!(entity.getIntegral().intValue() == oldData.getIntegral())) {
				//不相等，表示积分变更
				float diffIntegral = entity.getIntegral() - oldData.getIntegral();
				UserBaseEntity oldLogUser = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserName, oldData.getUserName()));
				if (null!=oldLogUser){
					integralYearLogService.addYearIntegral(oldLogUser.getUserNumber(),oldLogUser.getUserName(),year,diffIntegral,0);
				}

			}

		} else {
			//表示用户名称变更了
			//1.先删除旧用户的积分
			UserBaseEntity oldLogUser = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserName, oldData.getUserName()));
			if (null!=oldLogUser){
				float integral=0-oldData.getIntegral();//要扣除的积分
				integralYearLogService.addYearIntegral(oldData.getUserNumber(),oldData.getUserName(),year,integral,0);
			}

			//2.添加新用户的积分
			UserBaseEntity newLogUser = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserName, entity.getUserName()));
			if (null==newLogUser)throw new TrainingServiceException("未找到此人:"+entity.getUserName());
			integralYearLogService.addYearIntegral(newLogUser.getUserNumber(),newLogUser.getUserName(),year,entity.getIntegral(),0);

		}


		return this.updateById(entity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteIntegral(Long integralLogId) {
		IntegralLogEntity integralLogEntity = this.getById(integralLogId);
		String userNumber = integralLogEntity.getUserNumber();
		//1.个人积分扣除
		UserBaseEntity userBaseEntity = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserNumber, userNumber));
		if (null != userBaseEntity) {
			userBaseEntity.setIntegral(userBaseEntity.getIntegral() - integralLogEntity.getIntegral());
			userBaseService.updateById(userBaseEntity);
		}
		//2.年度积分扣除  按照被删除的积分项录入时间去扣除对应年度的积分
		String year = DateUtil.format(integralLogEntity.getCreateTime(), "yyyy");
		IntegralYearLogEntity integralYearLogEntity = integralYearLogService.getOne(Wrappers.<IntegralYearLogEntity>query().lambda()
			.eq(IntegralYearLogEntity::getYear, year)
			.eq(IntegralYearLogEntity::getUserNumber, integralLogEntity.getUserNumber()));
		if (null != integralYearLogEntity) {
			if (integralYearLogEntity.getIntegral() > 0) {
				integralYearLogEntity.setIntegral(integralYearLogEntity.getIntegral() - integralLogEntity.getIntegral());
			}
			if (integralYearLogEntity.getIntegral() < 0) integralYearLogEntity.setIntegral((float) 0);
			integralYearLogService.updateById(integralYearLogEntity);
		}

		//3.积分项删除
		return this.removeById(integralLogId);
	}


	@Override
	public IntegralLogVO generalIntegralByCourse(CourseEntity entity) {
		IntegralLogVO vo = new IntegralLogVO();
		vo.setIntegral(entity.getIntegral());
		vo.setPeriod(Float.valueOf(entity.getPeriod()));
		vo.setIntegralResourcesId(entity.getId());
		vo.setIntegralType(IntegralType.COURSE.getCode());

		vo.setIntegralOrigin(IntegralType.COURSE.getValue());
		vo.setProjectOrigin(entity.getName());
		vo.setRecordDate(org.springblade.core.tool.utils.DateUtil.formatDate(new Date()));
		return vo;
	}

	@Override
	public IntegralLogVO generalIntegralByExam(PaperReleaseEntity entity) {
		IntegralLogVO vo = new IntegralLogVO();
		vo.setIntegral(entity.getIntegral());
		vo.setPeriod(Float.valueOf(entity.getPeriod()));
		vo.setIntegralResourcesId(entity.getId());
		vo.setIntegralType(IntegralType.EXAM.getCode());
		vo.setIntegralOrigin(IntegralType.EXAM.getValue());
		vo.setProjectOrigin(entity.getReleaseName());
		vo.setRecordDate(org.springblade.core.tool.utils.DateUtil.formatDate(new Date()));


		return vo;
	}

	@Override
	public IntegralLogVO generalIntegralByTraining(IntegralTrainingEntity entity) {

		IntegralLogVO vo = new IntegralLogVO();
		vo.setIntegral(entity.getIntegral());
		vo.setPeriod((float) 0);
		vo.setIntegralResourcesId(entity.getId());
		vo.setIntegralType(IntegralType.TRAINING.getCode());
		vo.setIntegralOrigin(IntegralType.TRAINING.getValue());
		vo.setProjectOrigin(entity.getTrainingName());
		vo.setRecordDate(org.springblade.core.tool.utils.DateUtil.formatDate(new Date()));
		return vo;
	}

	@Override
	public IntegralLogVO generalIntegralByIntegral(IntegralLogEntity entity) {
		IntegralLogVO vo = IntegralLogWrapper.build().entityVO(entity);
		if (Func.isEmpty(entity.getIntegralType()))vo.setIntegralType(IntegralType.TRAINING.getCode());
		if (Func.isEmpty(entity.getIntegralOrigin()))vo.setIntegralOrigin(IntegralType.TRAINING.getValue());
		return vo;
	}

}
